package com.quanyan.place.biz.impl;

import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.exception.BizException;
import com.quanyan.common.utils.ObjectUtil;
import com.quanyan.place.biz.ConfigService;
import com.quanyan.place.biz.redis.ConfigCacheDao;
import com.quanyan.place.biz.redis.impl.ConfigCacheDaoImpl;
import com.quanyan.place.entity.Cagetory;
import com.quanyan.place.entity.CagetoryExample;
import com.quanyan.place.entity.Dict;
import com.quanyan.place.entity.DictExample;
import com.quanyan.place.entity.TbCity;
import com.quanyan.place.entity.TbCityExample;
import com.quanyan.place.entity.TbCityRegion;
import com.quanyan.place.entity.TbCityRegionExample;
import com.quanyan.place.entity.TbCommonParameter;
import com.quanyan.place.entity.TbCommonParameterExample;
import com.quanyan.place.entity.TbDistrict;
import com.quanyan.place.entity.TbDistrictExample;
import com.quanyan.place.entity.TbProvince;
import com.quanyan.place.entity.TbProvinceExample;
import com.quanyan.place.entity.apiresp.RespCategory;
import com.quanyan.place.entity.apiresp.RespCity;
import com.quanyan.place.entity.apiresp.RespCityInfo;
import com.quanyan.place.entity.base.apiresp.RespDistrict;
import com.quanyan.place.mapper.CagetoryMapper;
import com.quanyan.place.mapper.DictMapper;
import com.quanyan.place.mapper.TbCityMapper;
import com.quanyan.place.mapper.TbCityRegionMapper;
import com.quanyan.place.mapper.TbCommonParameterMapper;
import com.quanyan.place.mapper.TbDistrictMapper;
import com.quanyan.place.mapper.TbProvinceMapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author dongsheng.lin
 * @date 2017/5/1510:25
 */
@Service
public class ConfigServiceImpl implements ConfigService {

    private final static Logger logger = LoggerFactory.getLogger(ConfigCacheDaoImpl.class);

    private final static String SYSTEM = "场馆系统";

    /**
     * 过期时间
     */
    private final static int EXPIRE_TIME_MINUTE = 60 * 1;

    private final static int EXPIRE_TIME_FIVE_MINUTE = 60 * 5;

    private final static int EXPIRE_TIME_HOUR = 60 * 60;

    private final static int EXPIRE_TIME_DAY = 60 * 60 * 24;

    @Autowired
    private ConfigCacheDao configCacheDao;

    @Autowired
    private TbCommonParameterMapper tbCommonParameterMapper;

    @Autowired
    private CagetoryMapper cagetoryMapper;

    @Autowired
    private TbProvinceMapper tbProvinceMapper;

    @Autowired
    private TbCityMapper tbCityMapper;

    @Autowired
    private TbDistrictMapper tbDistrictMapper;

    @Autowired
    private DictMapper dictMapper;

    @Autowired
    private TbCityRegionMapper tbCityRegionMapper;

    @Override
    public List<TbCommonParameter> getCommonParameters() {
        List<TbCommonParameter> tbCommonParameterList  =  configCacheDao.getCommonParameterFromCache();
        if(CollectionUtils.isEmpty(tbCommonParameterList)){
            TbCommonParameterExample example = new TbCommonParameterExample();
            TbCommonParameterExample.Criteria criteria = example.createCriteria();
            criteria.andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
            tbCommonParameterList = tbCommonParameterMapper.selectByExample(example);
            if(CollectionUtils.isEmpty(tbCommonParameterList)){
                logger.error(SYSTEM + ":从数据库查询系统配置项失败！");
                throw new BizException(SYSTEM + ":从数据库查询系统配置项失败！");
            }
            configCacheDao.setCommonParameterToCache(tbCommonParameterList);
        }
        return tbCommonParameterList;
    }

    @Override
    public TbCommonParameter getCommonParameter(String parameterKey) {
        List<TbCommonParameter> tbCommonParameters = configCacheDao.getCommonParameterFromCache();
        if(CollectionUtils.isNotEmpty(tbCommonParameters) && tbCommonParameters.size() > 0){
            for (TbCommonParameter commonParameter : tbCommonParameters){
                if(commonParameter.getParameterKey().equals(parameterKey)){
                    return commonParameter;
                }
            }
        }else {
            List<TbCommonParameter> tbCommonParameterList = this.getCommonParameters();
            for(TbCommonParameter commonParameter : tbCommonParameterList){
                if(commonParameter.getParameterKey().equals(parameterKey)){
                    return commonParameter;
                }
            }
        }
        return null;
    }

    @Override
    public List<RespCategory> getSysCategroyInfo() {
        List<RespCategory> respCategoryList = configCacheDao.getSysCategroyInfoFromCache();
        if(CollectionUtils.isEmpty(respCategoryList)){
            CagetoryExample cagetoryExample = new CagetoryExample();
            cagetoryExample.createCriteria().andIsDeleteEqualTo(Constants.IS_DELETE_FALSE).andIsEnableEqualTo(Constants.IS_ENABLE_TRUE);
            List<Cagetory> cagetories = cagetoryMapper.selectByExample(cagetoryExample);
            if(CollectionUtils.isEmpty(cagetories)){
                logger.error(SYSTEM + ":从数据库查询运动类目失败！");
                throw new BizException(SYSTEM + ":从数据库查询运动类目失败！");
            }
            respCategoryList = new ArrayList<>();
            for(Cagetory cagetory : cagetories){
                RespCategory respCategory = new RespCategory();
                BeanUtils.copyProperties(cagetory, respCategory);
                respCategoryList.add(respCategory);
            }
            configCacheDao.setSysCategroyInfoToCache(respCategoryList);
        }
        return respCategoryList;
    }

    @Override
    public List<TbProvince> getProvinces() {
        List<TbProvince> tbProvinces = configCacheDao.getProvincesFromCache();
        if(CollectionUtils.isEmpty(tbProvinces)){
            TbProvinceExample example = new TbProvinceExample();
            example.createCriteria().andIsEnableEqualTo(1);
            example.setOrderByClause("priority");
            tbProvinces = tbProvinceMapper.selectByExample(example);
            if(CollectionUtils.isEmpty(tbProvinces)){
                logger.error("从数据库查询省份列表失败！");
                throw new BizException(SYSTEM + ": 从数据库查询省份信息出错！");
            }
            configCacheDao.setProvincesToCache(tbProvinces);
        }
        return tbProvinces;
    }

    @Override
    public PageObj<List<TbProvince>> getProvincesByPage(int pageNum, int pageSize, String keyWords) {
        List<TbProvince> provincesList = this.getProvinces();
        List<TbProvince> resultList = new ArrayList<>();
        if(StringUtils.isNotEmpty(keyWords)){
            for(TbProvince tbProvince : provincesList){
                if(StringUtils.isNotEmpty(tbProvince.getName()) && tbProvince.getName().contains(keyWords)){
                    resultList.add(tbProvince);
                }
            }
            int total = resultList.size();
            int highEndpoint = total < (pageNum + 1) * pageSize ? total : (pageNum + 1) * pageSize;
            resultList = resultList.subList(pageNum * pageSize, highEndpoint);
            return PageObj.create(total, pageNum, pageSize, resultList);
        }
        for (TbProvince tbProvince : provincesList){
            resultList.add(tbProvince);
        }
        int highEndpoint = provincesList.size() < (pageNum + 1) * pageSize ? provincesList.size() : (pageNum + 1) * pageSize;
        resultList = resultList.subList(pageNum * pageSize, highEndpoint);
        return PageObj.create(provincesList.size(), pageNum, pageSize, resultList);
    }

    @Override
    public List<TbCity> getCities() {
        List<TbCity> tbCityList = configCacheDao.getCitiesFromCache();
        if(CollectionUtils.isEmpty(tbCityList)){
            TbCityExample example = new TbCityExample();
            example.createCriteria().andIsEnableEqualTo(Constants.IS_YES).andIsActiveEqualTo(Constants.IS_ACTIVE);
            tbCityList = tbCityMapper.selectByExample(example);
            if(CollectionUtils.isEmpty(tbCityList)){
                logger.error(SYSTEM + ":从数据库查询城市列表失败！");
                throw new BizException(SYSTEM + ":从数据库查询城市列表失败！");
            }
            configCacheDao.setCitiesToCache(tbCityList);
        }
        return tbCityList;
    }

    @Override
    public TbCity getCity(int cityId) {
        List<TbCity> tbCityList = this.getCities();
        for(TbCity tbCity : tbCityList){
            if(tbCity.getId().intValue() == cityId){
                return tbCity;
            }
        }
        return null;
    }

    @Override
    public PageObj<List<TbCity>> getCitiesByPage(Integer provinceId, Integer pageNum, Integer pageSize, String keyWords) {
        List<TbCity> tbCities = new ArrayList<>();
        List<TbCity> tbCityList = this.getCities();
        if(CollectionUtils.isNotEmpty(tbCityList)){
            if(ObjectUtil.isNotObjectEmpty(provinceId)){
                if(StringUtils.isNotEmpty(keyWords)){
                    for(TbCity tbCity : tbCityList){
                        if(tbCity.getProvinceId().intValue() == provinceId && tbCity.getName().contains(keyWords)){
                            tbCities.add(tbCity);
                        }
                    }
                }else{
                    for(TbCity tbCity : tbCityList){
                        if(tbCity.getProvinceId().intValue() == provinceId){
                            tbCities.add(tbCity);
                        }
                    }
                }
            }else{
                if(StringUtils.isNotEmpty(keyWords)){
                    for(TbCity tbCity : tbCityList){
                        if(tbCity.getName().contains(keyWords)){
                            tbCities.add(tbCity);
                        }
                    }
                }else{
                    tbCities.addAll(tbCityList);
                }
            }
            int total = tbCities.size();
            int highEndpoint = total < (pageNum + 1) * pageSize ? total : (pageNum + 1) * pageSize;
            tbCities = tbCities.subList(pageNum * pageSize, highEndpoint);
            return PageObj.create(total, pageNum, pageSize, tbCities);
        }
        return PageObj.create(0, pageNum, pageSize,tbCities);
    }

    @Override
    public List<TbDistrict> getDistricts() {
        List<TbDistrict> tbDistrictList = configCacheDao.getDistrictsFromCache();
        if(CollectionUtils.isEmpty(tbDistrictList)){
            TbDistrictExample example  = new TbDistrictExample();
            example.setOrderByClause("priority");
            tbDistrictList =  tbDistrictMapper.selectByExample(example);
            if(CollectionUtils.isEmpty(tbDistrictList)){
                logger.error(SYSTEM + ":从数据库中查询地区失败！");
                throw new BizException(SYSTEM + ":从数据库中查询地区失败！");
            }
            configCacheDao.setDistrictsToCache(tbDistrictList);
        }
        return tbDistrictList;
    }

    @Override
    public TbDistrict getDistrictById(int districtId) {
        if(districtId <= 0){
            logger.error("districtId(区域id)必须大于0！");
            throw new BizException("districtId(区域id)必须大于0！");
        }
        List<TbDistrict> tbDistricts = this.getDistricts();
        if(CollectionUtils.isNotEmpty(tbDistricts)){
            for(TbDistrict tbDistrict : tbDistricts){
                if(tbDistrict.getId().intValue() == districtId){
                    return tbDistrict;
                }
            }
        }
        return null;
    }

    @Override
    public List<RespDistrict> getDistrictsByCityId(int cityId) {
        if(cityId <= 0){
            logger.error(SYSTEM + ":cityId(城市id)必须大于0！");
            throw new BizException(SYSTEM + ":cityId(城市id)必须大于0！");
        }
        List<RespDistrict> respDistrictList = configCacheDao.getDistrictsByCityIdFromCache(cityId);
        if(CollectionUtils.isEmpty(respDistrictList)){
            TbDistrictExample example = new TbDistrictExample();
            example.createCriteria().andCityIdEqualTo(cityId);
            List<TbDistrict> tbDistricts = tbDistrictMapper.selectByExample(example);
            if(CollectionUtils.isEmpty(tbDistricts)){
                logger.error(SYSTEM + ":从数据库查询区域列表出错！");
                throw new BizException(SYSTEM + ":从数据库查询区域列表出错！");
            }
            for(TbDistrict tbDistrict : tbDistricts){
                RespDistrict respDistrict = new RespDistrict();
                BeanUtils.copyProperties(tbDistrict,respDistrict);
                respDistrictList.add(respDistrict);
            }
            RespCityInfo respCityInfo = new RespCityInfo();
            RespCity respCity = new RespCity();
            respCityInfo.setRespDistrict(respDistrictList);
            TbCity tbCity = this.getCity(cityId);
            BeanUtils.copyProperties(tbCity,respCity);
            respCityInfo.setRespCity(respCity);
            configCacheDao.setDistrictsByCityIdToCache(respCityInfo);
        }
        return respDistrictList;
    }

    @Override
    public HashMap<String, String> getDictsByTagGroupToCache(String tagGroup) {
        if(StringUtils.isEmpty(tagGroup)){
            logger.error(SYSTEM + ":字典组别类型不能为空！");
            throw new BizException(SYSTEM + ":字典组别类型不能为空！");
        }
        HashMap<String,String> resultMap = configCacheDao.getDictsByTagGroupToCache(tagGroup);
        if(resultMap == null || resultMap.isEmpty()){
            List<Dict> dicts = dictMapper.selectByExample(new DictExample());
            if(CollectionUtils.isEmpty(dicts)){
                logger.error(SYSTEM + ":从数据库中取出字典数据出错！");
               throw new  BizException(SYSTEM + ":从数据库中取出字典数据出错！");
            }

            /*** 把所有的tag_group去重放入Set集合 ***/
            Set<String> tagGroups = new HashSet<>();
            for(Dict dict : dicts){
                tagGroups.add(dict.getTagGroup());
            }
            /*** 依据tag_group把对应的值放入redis ***/
            for(String group : tagGroups){
                HashMap<String,String> dictMap = new HashMap<>();
                for(Dict dict : dicts){
                    if(dict.getTagGroup().equals(group)){
                        dictMap.put(dict.getDataKey(),dict.getDataValue());
                    }
                }
                configCacheDao.setDictsByTagGroupToCache(group,dictMap);
            }
            resultMap = configCacheDao.getDictsByTagGroupToCache(tagGroup);
        }
        return resultMap;
    }

    @Override
    public List<TbCityRegion> getRegionByCityId(int cityId) {
        List<TbCityRegion> result = new ArrayList<>();
        if(cityId <= 0){
            logger.error(SYSTEM + ":cityId(城市id)必须大于0！");
            throw new BizException(SYSTEM + ":cityId(城市id)必须大于0！");
        }
        List<TbCityRegion> regionList = configCacheDao.getRegionByCityIdFromCache();
        if(CollectionUtils.isEmpty(regionList)){
            TbCityRegionExample example = new TbCityRegionExample();
            example.createCriteria().andCityIdEqualTo(cityId).andIsDeleteEqualTo(Constants.IS_DELETE_FALSE);
            regionList = tbCityRegionMapper.selectByExample(example);
            if(CollectionUtils.isEmpty(regionList)){
                logger.error(SYSTEM + ":从数据库取出的自定义城市区域列表为空！");
            }else{
                configCacheDao.setCityRegionsToCache(regionList);
                for(TbCityRegion tbCityRegion : regionList){
                    if(tbCityRegion.getCityId().intValue() == cityId){
                        result.add(tbCityRegion);
                    }
                }
            }
        }
        return result;
    }


}
